package com.fiberhome.opticalbox.ui.keyboard810;

import android.app.Activity;
import android.os.Bundle;
import android.view.LayoutInflater;
import android.view.MotionEvent;
import android.view.View;
import android.view.View.OnTouchListener;
import android.view.ViewGroup;
import android.view.animation.Animation;
import android.view.animation.Animation.AnimationListener;
import android.view.animation.AnimationSet;
import android.view.animation.DecelerateInterpolator;
import android.widget.FrameLayout;
import android.widget.ImageView;
import android.widget.TextView;

import com.fiberhome.opticalbox.R;
import com.fiberhome.opticalbox.BaseFragment;
import com.fiberhome.opticalbox.utils.AnimUtil;
import com.fiberhome.opticalbox.utils.BaseUtil;
import com.fiberhome.opticalbox.utils.LogUtil;

public class KeyboardTouchFragment extends BaseFragment {

	private MBaseRCActivity holder;

	private float downX, downY;
	private long cmdSendFlag;

	private FrameLayout layContent;
	private ImageView imgFlag;
	private TextView txPoint;

	private float fixAnimWidth, fixAnimHeight;
	private float clickEdge;

	@Override public void onAttach(Activity activity) {
		super.onAttach(activity);
		if (activity instanceof MBaseRCActivity) {
			holder = (MBaseRCActivity) activity;
			fixAnimHeight = BaseUtil.dip2px(holder, 60) + BaseUtil.dip2px(holder, 30);
			fixAnimWidth = BaseUtil.dip2px(holder, 30);
			clickEdge = BaseUtil.dip2px(holder, 5);
		}
	}

	public void sendKey(Integer keyCode, int action) {
		if (holder != null) {
			holder.sendKey(keyCode, action);
		}
	}

	@Override public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
		View view = inflater.inflate(R.layout.ob_fragment_keyboard_touch, null);
		layContent = (FrameLayout) view.findViewById(R.id.lay_content);
		layContent.setOnTouchListener(onTouchListener);
		imgFlag = (ImageView) view.findViewById(R.id.img_flag);

		txPoint = (TextView) view.findViewById(R.id.tx_point);
		view.findViewById(R.id.lay_test).setVisibility(View.INVISIBLE);

		view.findViewById(R.id.btn_key_list).setOnTouchListener(onKeyTouchListener);
		view.findViewById(R.id.btn_key_home).setOnTouchListener(onKeyTouchListener);
		view.findViewById(R.id.btn_key_back).setOnTouchListener(onKeyTouchListener);
		return view;
	}

	private OnTouchListener onTouchListener = new OnTouchListener() {
		private final int UP = 7;
		private final int DOWN = 8;
		private final int LEFT = 9;
		private final int RIGHT = 10;
		private final int CLICK = 11;
		private boolean sendFlag = false;

		@Override public boolean onTouch(View v, MotionEvent event) {
			switch (event.getAction()) {
			case MotionEvent.ACTION_DOWN:
				downX = event.getRawX();
				downY = event.getRawY();
				sendFlag = false;
				cmdSendFlag = System.currentTimeMillis();
			case MotionEvent.ACTION_MOVE:
				txPoint.setText("x:" + event.getRawX() + ",y" + event.getRawY());

				long currentSendFlag = System.currentTimeMillis();
				if (!sendFlag && currentSendFlag - cmdSendFlag > 400) {
					sendGestureEvent(event);
				}
				break;
			case MotionEvent.ACTION_CANCEL:
			case MotionEvent.ACTION_UP:
				if (!sendFlag) {
					sendGestureEvent(event);
				}
				break;
			}
			return true;
		}

		private void sendGestureEvent(MotionEvent event) {
			int keyCode = computeGesture(event);
			animGesture(downX, downY, event.getRawX(), event.getRawY(), keyCode);
			LogUtil.w("touch down and up");
			sendKey(keyCode, MotionEvent.ACTION_DOWN);
			sendKey(keyCode, MotionEvent.ACTION_UP);
			sendFlag = true;
		}

		private Integer computeGesture(MotionEvent event) {
			float moveX = event.getRawX() - downX;
			float moveY = event.getRawY() - downY;

			if (Math.abs(moveX) < clickEdge && Math.abs(moveX) < clickEdge) { // click
				return CLICK;
			} else {
				if (moveX > 0) { // down
					if (Math.abs(moveX) / Math.abs(moveY) > 1) {
						return RIGHT;
					} else {
						return moveY > 0 ? DOWN : UP;
					}
				} else { // up
					if (Math.abs(moveX) / Math.abs(moveY) > 1) {
						return LEFT;
					} else {
						return moveY > 0 ? DOWN : UP;
					}
				}
			}
		}

		private void animGesture(float startX, float startY, float endX, float endY, int direction) {
			startY = startY - fixAnimHeight;
			endY = endY - fixAnimHeight;
			startX = startX - fixAnimWidth;
			endX = endX - fixAnimWidth;
			imgFlag.clearAnimation();
			AnimationSet anim = AnimUtil.init().addAlpha(1f, 0f)
					.addTranslate(startX, endX, startY, endY, 0, 300, new DecelerateInterpolator()).create();

			switch (direction) {
			case UP:
				imgFlag.setImageResource(R.drawable.ob_key_touch_up);
				break;
			case DOWN:
				imgFlag.setImageResource(R.drawable.ob_key_touch_down);
				break;
			case LEFT:
				imgFlag.setImageResource(R.drawable.ob_key_touch_left);
				break;
			case RIGHT:
				imgFlag.setImageResource(R.drawable.ob_key_touch_right);
				break;
			case CLICK:
			default:
				imgFlag.setImageResource(R.drawable.ob_key_touch_click);
				break;
			}
			imgFlag.setVisibility(View.VISIBLE);
			anim.setAnimationListener(new AnimationListener() {
				@Override public void onAnimationStart(Animation animation) {
				}

				@Override public void onAnimationRepeat(Animation animation) {
				}

				@Override public void onAnimationEnd(Animation animation) {
					imgFlag.setVisibility(View.GONE);
				}
			});
			imgFlag.startAnimation(anim);
		}
	};

	private OnTouchListener onKeyTouchListener = new OnTouchListener() {
		@Override public boolean onTouch(View view, MotionEvent event) {
			if (view.getTag() == null) {
				LogUtil.e("KeyboardTouchFragment keyCode not set");
				// showToast("KeyboardTouchFragment keyCode not set");
				return false;
			}

			int keyCode;
			try {
				keyCode = Integer.parseInt(view.getTag().toString());
			} catch (Exception e) {
				LogUtil.e("KeyboardTouchFragment keyCode parse error");
				// showToast("KeyboardTouchFragment keyCode parse error");
				return false;
			}
			switch (event.getAction()) {
			case MotionEvent.ACTION_DOWN:
				sendKey(keyCode, MotionEvent.ACTION_DOWN);
				break;
			case MotionEvent.ACTION_CANCEL:
			case MotionEvent.ACTION_UP:
				sendKey(keyCode, MotionEvent.ACTION_UP);
				break;
			}
			return false;
		}
	};
}
